package com.jf.anmocker.plugin.transform;

import com.android.build.api.transform.Context
import com.android.build.api.transform.DirectoryInput
import com.android.build.api.transform.JarInput;
import com.android.build.api.transform.QualifiedContent;
import com.android.build.api.transform.Transform;
import com.android.build.api.transform.TransformException;
import com.android.build.api.transform.TransformInput;
import com.android.build.api.transform.TransformOutputProvider;
import com.android.build.gradle.internal.pipeline.TransformManager;
import org.apache.commons.io.FileUtils
import org.apache.commons.codec.digest.DigestUtils

import org.gradle.api.Project;

/**
 * @Class: MyTransformG
 * @Description:
 * @author:
 * @Date: 2022/9/21
 */
public class MyTransformG extends Transform {

    private static Project project;

    public MyTransformG(Project mProject) {
        project = mProject;
        printCopyRight()
    }

    // 指定 Transform 的名称，该名称还会用于组成 Task 的名称
    // 格式为 transform[InputTypes]With[name]For[Configuration]
    @Override
    public String getName() {
        return "TransformWithMyScan";
    }

    /**
     * 需要处理的数据类型，有两种枚举类型
     * CLASSES 代表处理的 java 的 class 文件，RESOURCES 代表要处理 java 的资源
     * @return
     */
    @Override
    public Set<QualifiedContent.ContentType> getInputTypes() {
        return TransformManager.CONTENT_CLASS;
    }

    /**
     * 指 Transform 要操作内容的范围，官方文档 Scope 有 7 种类型：
     * 1. EXTERNAL_LIBRARIES        只有外部库
     * 2. PROJECT                   只有项目内容
     * 3. PROJECT_LOCAL_DEPS        只有项目的本地依赖(本地jar)
     * 4. PROVIDED_ONLY             只提供本地或远程依赖项
     * 5. SUB_PROJECTS              只有子项目。
     * 6. SUB_PROJECTS_LOCAL_DEPS   只有子项目的本地依赖项(本地jar)。
     * 7. TESTED_CODE               由当前变量(包括依赖项)测试的代码
     * @return
     */
    @Override
    public Set<? super QualifiedContent.Scope> getScopes() {
        return TransformManager.SCOPE_FULL_PROJECT;
    }

    // 指定是否支持增量编译
    @Override
    public boolean isIncremental() {
        return false;
    }

    /**
     * 打印提示信息
     */
    static void printCopyRight() {
        println();
        println("####################################################################");
        println("########                                                    ########");
        println("########                                                    ########");
        println("########                欢迎使用 AnMockerG编译插件             ########");
        println("########              使用过程中碰到任何问题请联系我们            ########");
        println("########                                                     ########");
        println("########                                                     ########");
        println("#####################################################################");
        println();
    }

    // 核心 API
    public void transform(
            Context context,
            Collection<TransformInput> inputs,
            Collection<TransformInput> referencedInputs,
            TransformOutputProvider outputProvider,
            boolean isIncremental) throws IOException, TransformException, InterruptedException {

        if(!isIncremental){
            outputProvider.deleteAll();
        }
        // Transform 的 inputs 有两种类型，一种是目录，一种是 jar 包，要分开遍历
        inputs.each { TransformInput input ->
            //遍历目录
            println("Transform directoryInputs start.")
            input.directoryInputs.each { DirectoryInput directoryInput ->
                //获取 output 目录
                def dest = outputProvider.getContentLocation(directoryInput.name,
                        directoryInput.contentTypes, directoryInput.scopes,
                        Format.DIRECTORY)
                // 将 input 的目录复制到 output 指定目录
                FileUtils.copyDirectory(directoryInput.file, dest)
            }

            //遍历 jar
            println("Transform jarInputs start.")
            input.jarInputs.each { JarInput jarInput ->
                /**重命名输出文件（同目录copyFile会冲突）*/
                String destName = jarInput.file.name
                /**截取文件路径的 md5 值重命名输出文件,因为可能同名,会覆盖*/
                def hexName = DigestUtils.md5Hex(jarInput.file.absolutePath).substring(0, 8)
                /** 获取 jar 名字*/
                if (destName.endsWith(".jar")) {
                    destName = destName.substring(0, destName.length() - 4)
                }

                //不做任何改变输出
                //File copyJarFile = jarInput.file
                //更新内容
                File copyJarFile = MyJarAnalyticsInjectG.injectJar(jarInput.file.absolutePath, project)

                //生成输出路径
                def dest = outputProvider.getContentLocation(destName + hexName,
                        jarInput.contentTypes, jarInput.scopes, Format.JAR)
                // 将 input 的目录复制到 output 指定目录
                FileUtils.copyFile(copyJarFile, dest)
            }
        }
    }

    // 指定是否支持缓存
    public boolean isCacheable() {
        return false;
    }
}
